# Initialization
StateFilePath := cat("States/", parBaseFileName, ".state"):
printf ("\nParameters:\nparBaseFileName=%a, parCD=%a, parJobPrefix=%a\n\n", 
          parBaseFileName, parCD, parJobPrefix);

printf ("pwd = %a\n", currentdir());
printf ("kernelopts(datalimit) = %a MB, kernelopts(stacklimit) = %a MB\n", 
        trunc(kernelopts(datalimit)/1024), trunc(kernelopts(stacklimit)/1024));
printf ("kernelopts(version) = %a\n", kernelopts(version));

try #WSParser:Skip#
  interface(labelling=false);
  read `global/mc/JetsTest.s`;
  read `global/mc/CommonProc.mc`;
  
catch: 
  printf("Error, initialization failed:%Q\n", 
      StringTools[FormatMessage](lastexception[2..-1]));
  `quit` (51);
end try;

detailedReportFile := cat("Logs.Detailed/",parBaseFileName,".log") ;
reportfile := cat("Logs.Detailed/",parBaseFileName,".r.log") ;

try #WSParser:Skip#
  read sprintf("global/mc/%s.init.mc", parJobPrefix) ; #WSParser:Parse#
catch:
  printf("Error while reading mc/%s.init.mc:%Q\n", 
    parJobPrefix, StringTools[FormatMessage](lastexception[2..-1]));
   `quit` (52);
end try; 

#printlevel := 4; #WSParser:Skip#
#kernelopts(datalimit=(kernelopts(datalimit)-5*1024)); #WSParser:Skip#
#reporting(pd = 5, cc = 5, derive = 5, run = 5, resolve = 5); #WSParser:Skip#
  

# Read initial data
try #WSParser:Skip#
  read sprintf("%s.runme", parBaseFileName); #WSParser:Parse#Deep#  
  printf("File %s.runme read done.\n", parBaseFileName);
catch:
  print("put/nonzero failed:");
  print(StringTools[FormatMessage](lastexception[2..-1]));
  writetofile(cat(parBaseFileName,  ".err"), 
      sprintf("Error: %q\n",StringTools[FormatMessage](lastexception[2..-1])));
  `quit` (53);
end try;
printf("\ndependence() =\n");
print(    dependence());


# Run computations  
try
  printf("\n# Lets do 'run(S);'...\n");
  run(S);
  printf("\n# 'run(S);' is done.\n");
  ThrowExceptionWhenNonImportant();
  
  if evalb(assigned(`resolve/result/suppressedminsize`) and `resolve/result/suppressedminsize` <> NULL) then
    ratio := `resolve/result/suppressedminsize`/maxsize*2;
    printf("Trying to increase sizes by ratio %a.\n", ratio);
    ressize := trunc(ressize*ratio);  putsize := trunc(putsize*ratio);  maxsize := trunc(maxsize*ratio);
    printf("ressize=%a, putsize=%a, maxsize=%a\n", ressize, putsize, maxsize);  
    run(S);
    ThrowExceptionWhenNonImportant();
  fi;  

catch "TestOfNonImportantness failed" :
    try #WSParser:Skip#
     printf("Nonimportant state.\n");
     print(dependence());
     print('A'=map(eval,A));
     print('B'=map(eval,B));
     print('R'=map(eval,R));
     map(a -> printf("%a=%q\n", op(a), eval(op(a))), [indices(`dep/tab`)]);
     
    	writetofile( cat("Abandoned/", parBaseFileName, ".nonimportant"), 
    	   dependence(), 
    	   map(a -> sprintf("%a=%q\n", op(a), eval(op(a))), [indices(`dep/tab`)]),
    	   sprintf("A=%a\nB=%a\nR=%a\n%q\n", 
    	      map(eval,A), map(eval,B), map(eval,R),
    	      StringTools[FormatMessage](lastexception[2..-1])));  
    	writetofile(StateFilePath, "# Done");  	
    	print ("Done");
    	`quit` (7);
    catch:
    	printf("writetofile %s.nonimportant failed:%q\n", parBaseFileName, 
    	   StringTools[FormatMessage](lastexception[2..-1]));
    	writetofile(cat(parBaseFileName , ".err"), 
    	   sprintf("Error: %q\n",StringTools[FormatMessage](lastexception[2..-1])));
    	`quit` (55);
    end try ;  

catch "Matrix R equals zero.":
    try #WSParser:Skip#
     printf("Nonimportant state: Matrix R equals zero.\n");
     print(dependence(), 'R'=evalm(R));
    	writetofile( cat("Abandoned/", parBaseFileName, ".nonimportant"), dependence());  
    	writetofile(StateFilePath, "# Done");  	
    	print ("Done");
    	`quit` (7);
    catch:
    	printf("writetofile %s.nonimportant failed:%q\n", parBaseFileName, 
    	   StringTools[FormatMessage](lastexception[2..-1]));
    	writetofile(cat(parBaseFileName , ".err"), 
    	   sprintf("Error: %q\n",StringTools[FormatMessage](lastexception[2..-1])));
    	`quit` (55);
    end try ;  

catch "declared nonzero became zero":
    try #WSParser:Skip#
     printf("Nonimportant state: declared nonzero became zero.\n");
    	writetofile( cat("Abandoned/", parBaseFileName, ".non0to0"), RESOLVE);  
    	writetofile(StateFilePath, "# Done");  	
    	print ("Done");
    	`quit` (8);
    catch:
    	printf("writetofile %s.ce failed:%q\n", parBaseFileName, 
    	   StringTools[FormatMessage](lastexception[2..-1]));
    	writetofile(cat(parBaseFileName , ".err"), 
    	   sprintf("Error: %q\n",StringTools[FormatMessage](lastexception[2..-1])));
    	`quit` (55);
    end try ;  
      
catch "there are contradictory equations" :
    try #WSParser:Skip#
     printf("Nonimportant state: there are contradictory equations.\n");
    	writetofile( cat("Abandoned/", parBaseFileName, ".ce"), RESOLVE);  
    	writetofile(StateFilePath, "# Done");  	
    	print ("Done");
    	`quit` (2);
    catch:
    	printf("writetofile %s.ce failed:%q\n", parBaseFileName, 
    	   StringTools[FormatMessage](lastexception[2..-1]));
    	writetofile(cat(parBaseFileName , ".err"), 
    	   sprintf("Error: %q\n",StringTools[FormatMessage](lastexception[2..-1])));
    	`quit` (55);
    end try ;  

catch "numeric exception: division by zero" :    
    printf("Run failed: %q\n", StringTools[FormatMessage](lastexception[2..-1]));
    #printf("eqn/list=\n");
    #print(`eqn/list`); 
    printf("nonzero/s=%q\n", `nonzero/s`);
    print(`nonzero/s`);      
    printf("refresh/eqn/list=\n");
    print(`refresh/eqn/list`); 
    printf("refresh/nonzero/s=\n");
    print(`refresh/nonzero/s`); 
      
    try #WSParser:Skip#
      reportfilename := cat("Results/", parBaseFileName, ".divbyzero");
    	writetofile( reportfilename, 
    	   "Division by zero.\nRESOLVE, nonzero/s, refresh/eqn/list, refresh/nonzero/s: \n", 
         RESOLVE, `nonzero/s`, `refresh/eqn/list`, `refresh/nonzero/s`);
      writetofile(StateFilePath, "# Done");
    	print ("Done");
    	`quit` (3);
    catch:
    	printf("writetofile(%s)  failed: %q", reportfilename, 
    	   StringTools[FormatMessage](lastexception[2..-1]));
    	writetofile(cat(parBaseFileName , ".err"), 
    	   sprintf("Error: %q\n",StringTools[FormatMessage](lastexception[2..-1])));
    	`quit` (55);
    end try ; 
    
catch:
  	printf("Run unexpectedly failed: %q\n", StringTools[FormatMessage](lastexception[2..-1]));
  	printf("RESOLVE=%q\n", RESOLVE);
  	map(a -> printf("%a=%q\n", op(a), eval(op(a))), [indices(`dep/tab`)]);
    writetofile(cat(parBaseFileName , ".err"), 
        sprintf("Run unexpectedly failed.\nError: %q\n",StringTools[FormatMessage](lastexception[2..-1])));
    
    store(StateFilePath);    
    `quit` (54) ;
end try;

# Store final data state
try #WSParser:Skip#  
  CheckNonZero("");
  `CheckNonZero/Set` := [];
  store(StateFilePath);
  appendtofile(StateFilePath, "# Done");
catch:
  printf("store (%s) failed: %q\n", StateFilePath, 
      StringTools[FormatMessage](lastexception[2..-1]));
  writetofile(cat(parBaseFileName , ".err"), 
      sprintf("store(...) failed\nError: %q\n", StringTools[FormatMessage](lastexception[2..-1])));
  `quit` (56);
end try;
    
# Handle results
try #WSParser:Skip#
  if  assigned(`resolve/result/suppressedminsize`) 
  and `resolve/result/suppressedminsize` <> NULL 
  and type (RESOLVE,set) 
  and nops(RESOLVE)=0 then
      writetofile (cat(parBaseFileName , ".err"), 
         sprintf("'maxsize'=%a is too low.\n`resolve/result/suppressedminsize`=%a\nRESOLVE=%q\n",
                  maxsize, `resolve/result/suppressedminsize`, RESOLVE));
    `quit` (60);
  fi;
  
  if type (RESOLVE,set) then
    if nops(RESOLVE)=0 then
      # success
     	ReportSuccessState(parBaseFileName, "");
      
      #if cc() != {}  or map(normal@evalTD,[S1,S2,S3,S4,S5,S6]) != [0,0,0,0,0,0] then
      #	# TODO: Handle this correctly!
      #	print( "!!!!!!!!!!!!!!!!");
      #fi;      
             
      # final computations

      Z:=clear(pds);
      printf("clear(pds)=%q\n\n", Z);
     
      appendtofile(cat("Results/", parBaseFileName, ".success"), 
                   sprintf("\nclear(pds)=%Q\n",Z),
                   sprintf("\nclear(pds)=%Q\n",map(convert, Z, diff)));
      
     try
         printf ("\n\n-----------------------------------------\n");
         printf ("\n\n\nVarordering(function, reverse, degree);\n");
         Varordering(function, reverse, degree);
       #  #printf("reading %s.runme again...\n", parBaseFileName); 
       #  #read sprintf("%s.runme", parBaseFileName); #WSParser:Parse#
       #  #printf("reading done\n");
         S := Z; 
         Z := 'Z';
         run(S);
         store(cat("States/", parBaseFileName, ".frd.state"));
         if nops(RESOLVE)>0 then
            printf("frd: RESOLVE=%q\n", RESOLVE);
         else # success
            ReportSuccessState(cat(parBaseFileName, ".frd"), 
              "Done Varordering(function, reverse, degree): Run(Z):");  
            
            Z:=clear(pds);
            
            append2ft(cat("Results/", parBaseFileName, ".frd.success"), 
              sprintf("\nclear(pds)=%Q\n",Z),
              sprintf("\nclear(pds)=%Q\n",map(convert, Z, diff)));   
                 
         fi;
     catch:
       # note to the standard .success file about this failure
       append2ft(cat("Results/", parBaseFileName, ".success"),
          sprintf("\n\nWarning, run(Z) after Varordering(function, reverse, degree) failed: %q\n", 
                  StringTools[FormatMessage](lastexception[2..-1])));
       `quit` (4);
     end try;       
    else
      # resolve failed
      GenerateResultFiles(parBaseFileName, "global/States/", "Ready/");  
    fi;
  else
    # unexpected RESULT value
    write2ft (cat(parBaseFileName , ".err"), 
      sprintf("Resolve result is not a set.\nRESOLVE=%a\n", RESOLVE));
    `quit` (58);
  fi;
catch:
  write2ft(cat(parBaseFileName , ".err"), 
    sprintf("Results handling failed.\nError: %q\n", StringTools[FormatMessage](lastexception[2..-1])));
  `quit` (57);
end try;

printf("\nkernelopts(bytesalloc)=%a, kernelopts(bytesused)=%a, kernelopts(cputime)=%a\n", kernelopts(bytesalloc), kernelopts(bytesused), kernelopts(cputime)); #WSParser:Skip#
print ("Done"); #WSParser:Skip#
`quit` (0); #WSParser:Skip#


